package main

import (
	"bufio"
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"golang.org/x/net/html/charset"
	"golang.org/x/text/encoding"
	"golang.org/x/text/encoding/unicode"
	"golang.org/x/text/transform"
	"io"
	"io/ioutil"
	"my-crawler/pkg"
	"net/http"
)

/*串行版 用于简单测试*/
func main() {
	resp, err := http.Get(common.CRAWLERURL)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	//验证请求是否成功
	if resp.StatusCode != http.StatusOK {
		fmt.Sprintf("http code:%d", resp.StatusCode)
		return
	}
	/*
			预防乱码 (判断原网页是什么字符集，然后再通过x/text库转换成uft8的body)
			需要注意的是 不能重复使用resp.Body，因为io.Reader的读指针已经到末尾会返回空。
			所以需要生成一个NewReader将body暂存
		**  可选代码（因为不建议这么做 可以在爬虫前判断是否需要转字符集，
			然后确定原始字符集直接进行转义，避免读取两次Reader——网页本身字节很多 占用内存）
		**
	*/
	bodyReader := bufio.NewReader(resp.Body)
	encode := getCharSet(bodyReader)
	utf8Reader := transform.NewReader(bodyReader, encode.NewDecoder())
	all, _ := ioutil.ReadAll(utf8Reader)
	//all, _ := ioutil.ReadAll(resp.Body)

	//对结果进行处理
	operaResult(resp.Body)

	fmt.Printf("%s \n", all)
}

//可以正则 可以xpath 可以css选择器
func operaResult(r io.Reader) {
	doc, err := goquery.NewDocumentFromReader(r)
	if err != nil {
		fmt.Errorf("goquery: Load the HTML document failed! %v", err)
	}
	doc.Find("#cityList dd a").Each(func(i int, s *goquery.Selection) {
		// For each item found, get the title
		title := s.Text()
		href, _ := s.Attr("href")
		fmt.Printf("Region %d: title:%s url:%s \n", i, title, href)
	})
}

// x/net库可以根据前1024个字符串判断字符集
func getCharSet(r *bufio.Reader) encoding.Encoding {
	//这里不能直接读取resp.body
	newReader, err := r.Peek(1024)
	if err != nil {
		return unicode.UTF8 //默认返回一个 就不panic了
	}
	encode, _, _ := charset.DetermineEncoding(newReader, "")
	return encode
}
